package com.starblink.library.widget.product.parity

import android.annotation.SuppressLint
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.ColorDrawable
import android.view.View
import android.widget.LinearLayout
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.starblink.android.basic.adapter.BaseBindingVH
import com.starblink.android.basic.adapter.MutableAdapter
import com.starblink.android.basic.aroute.CommonRoute
import com.starblink.android.basic.ext.*
import com.starblink.basic.apollo.ext.ApolloValSetExt.apolloValue
import com.starblink.android.basic.extension.dp2px
import com.starblink.android.basic.extension.extraOf
import com.starblink.android.basic.extension.lazyOnNone
import com.starblink.android.basic.extension.navigationTo
import com.starblink.android.basic.sensorsdata.extension.trackData
import com.starblink.android.basic.sensorsdata.room.entity.SkAntEntity
import com.starblink.android.basic.sensorsdata.spm.GTrackerAssistUtils
import com.starblink.android.basic.sensorsdata.spm.cfg.SpmElementDef
import com.starblink.android.basic.sensorsdata.spm.event.TrackEvent
import com.starblink.android.basic.sensorsdata.spm.impl.SpmTrackHandler
import com.starblink.android.basic.user.UserDataCenter
import com.starblink.android.basic.util.bus.FlowBus
import com.starblink.android.basic.util.bus.FlowConst
import com.starblink.android.basic.util.bus.bean.FollowStoreEvent
import com.starblink.android.basic.util.post.CommonMutateManage
import com.starblink.android.basic.widget.dialog.BaseBottomSheetFragment
import com.starblink.basic.ext.load
import com.starblink.basic.route.RoutePage
import com.starblink.library.widget.R
import com.starblink.library.widget.databinding.CellParityInfoBinding
import com.starblink.library.widget.databinding.CellProductParityBinding
import com.starblink.library.widget.databinding.DialogProductParityBinding
import com.starblink.rocketreserver.fragment.ProductF
import com.starblink.rocketreserver.fragment.ProductOffer
import kotlin.math.roundToInt

/**
 *  Product Price parity dialog
 *  Create by yuanl at 2023/4/7
 **/
class PriceParityDialog : BaseBottomSheetFragment() {

    private lateinit var binding: DialogProductParityBinding


    private lateinit var product: ProductF
    private lateinit var listProduct: List<ProductOffer>
    private var spmPageValue: Int = 0


    private val list = arrayListOf<Any>()

    private val adapter by lazyOnNone {
        MutableAdapter(list).apply {
//            addVhDelegate {
//                PriceParityInfoCell(CellParityInfoBinding.inflate(it.inflater, it, false), listProduct.size) {
//                    dismiss()
//                }
//            }
            addVhDelegate {
                PriceParityCell(
                    spmPageValue = spmPageValue,
                    CellProductParityBinding.inflate(it.inflater, it, false),
                    pageTrackTag = this@PriceParityDialog.hashCode().toString()
                )
            }
        }
    }

    private fun onInitView() {

        binding.root.enableCorner(32.dp2px(), "top")

        list.apply {
            //add(product)
            addAll(listProduct)
        }
        binding.recycler.addItemDecoration(object : DividerItemDecoration(
            context,
            LinearLayout.VERTICAL
        ) {


            private val bound = Rect()

            override fun onDraw(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) {
                //super.onDraw(c, parent, state)
                drawable ?: return
                canvas.save()
                val left: Int
                val right: Int
                //noinspection AndroidLintNewApi - NewApi lint fails to handle overrides.
                if (parent.clipToPadding) {
                    left = parent.paddingLeft
                    right = parent.width - parent.paddingRight
                    canvas.clipRect(
                        left, parent.paddingTop, right,
                        parent.height - parent.paddingBottom
                    )
                } else {
                    left = 0
                    right = parent.width
                }
                val childCount = parent.childCount
                for (i in 1 until childCount - 1) {
                    val child = parent.getChildAt(i)
                    parent.getDecoratedBoundsWithMargins(child, bound)
                    val bottom = bound.bottom + child.translationY.roundToInt()
                    val top = bottom - drawable!!.intrinsicHeight
                    drawable!!.setBounds(left, top, right, bottom)
                    drawable!!.draw(canvas)
                }
                canvas.restore()
            }

        }.apply {
            setDrawable(object :
                ColorDrawable(requireContext().color(com.starblink.basic.style.R.color.sk_gray100)) {
                override fun getIntrinsicHeight(): Int = 1
            })
        })
        binding.recycler.layoutManager = LinearLayoutManager(context)
        binding.recycler.adapter = adapter


        PriceParityInfoCell(binding.layoutInfo, size = listProduct.size) {
            dismiss()
        }.onBind(product = product, position = 0)


        FlowBus.with<FollowStoreEvent>(FlowConst.FOLLOW_STORE_EVENT).register(this) { event ->
            if (event.id != null) {
                listProduct.forEachIndexed { index, it ->
                    if (event.id == it.merchantWeb?.merchantWebVOF?.id && event.followed != it.merchantWeb?.merchantWebVOF?.subOrNot) {
                        it.merchantWeb?.merchantWebVOF?.apolloValue("subOrNot", event.followed)
                        adapter.notifyItemChanged(index)
                    }
                }
            }
        }

        // 页面曝光
        SpmTrackHandler.addSingleTrackData(
            SkAntEntity(
                spmCnt = GTrackerAssistUtils.fetchPageValue(
                    spmPageValue
                ),
                event = TrackEvent.pageExposure.value,
            )
        )
    }

    override fun dismiss() {
        super.dismiss()
    }

    override fun getBindingRootView(): View {
        if (!::binding.isInitialized) {
            binding = DialogProductParityBinding.inflate(layoutInflater)
        }
        return binding.root
    }

    override fun initView() {
        onInitView()
    }

    companion object {

        @JvmStatic
        fun show(
            fragmentMgr: FragmentManager,
            product: ProductF,
            listProduct: List<ProductOffer>,
            spmPageValue: Int,
        ) {
            PriceParityDialog().apply {
                this.product = product
                this.listProduct = listProduct
                this.spmPageValue = spmPageValue
            }.show(
                fragmentMgr,
                "PriceParityDialog"
            )
        }

    }

}

internal class PriceParityInfoCell(
    binding: CellParityInfoBinding,
    val size: Int,
    val closeClick: () -> Unit,
) : BaseBindingVH<ProductF, CellParityInfoBinding>(binding) {

    @SuppressLint("StringFormatMatches")
    override fun onBind(product: ProductF, position: Int) {
        binding.img.enableCorner(16.dp2px())
        binding.img.load(product.mainImg)
        binding.tvBrandTag.visibleOrGone(product.brand?.isNotEmpty() == true) {
            text = product.brand
        }
        binding.tvName.text = product.title

        // 1.5.2_2 不要了
//        binding.tvVoteNum.visibleOrGone((product.voteNum ?: 0) > 0) {
//            text = context.getString(R.string.on_people_wish, "${product.voteNum!!}")
//        }

        val propertiesStr = StringBuilder()
        product.frontPropertyList?.mapNotNull { it.value }?.let {
            it.forEachIndexed { index, s ->
                propertiesStr.append(s)
                if (index < it.size - 1) {
                    propertiesStr.append(" | ")
                }
            }
        }
        // 1.5.2_2 不要了
//        binding.tvGoodsAtts.visibleOrGone(propertiesStr.isNotEmpty()) {
//            text = propertiesStr
//        }

        binding.tvTitle.visibleOrGone(size > 0) {
            text = context.getString(R.string.compare_price_n_stores, "${size}")
        }
        binding.btnClose.setOnClickListener {
            closeClick.invoke()
        }
    }

}

internal class PriceParityCell(
    var spmPageValue: Int,
    binding: CellProductParityBinding,
    val pageTrackTag: String,
) :
    BaseBindingVH<ProductOffer, CellProductParityBinding>(binding) {

    private fun spmMap(product: ProductOffer, position: Int): MutableMap<String, String> {
        return mutableMapOf(
            "id" to (product.id ?: ""),
            "productId" to (product.productId ?: ""),
            "standardSpuIds" to (product.standardSpuIds ?: ""),
            "type" to product.type.toString(),
            "merchantName" to (product.merchantWeb?.merchantWebVOF?.merchantName ?: ""),
            "index" to position.toString(),
        )
    }

    override fun onBind(model: ProductOffer, position: Int) {
        val merchant = model.merchantWeb?.merchantWebVOF
        binding.logo.load(merchant?.logo, merchant?.merchantName)
        binding.tvMerchantName.text = merchant?.merchantName

        binding.vPrice.visibleOrGone(model.price != null) {
            binding.vPrice.show(model.price!!, model.currency, model.currencySymbol)
        }

        binding.ivLowest.visibleOrGone(false)
        binding.ivDiscount.visibleOrGone(false)
        // 优先显示最低价标签，次之显示折扣标签
        if (model.minimumPriceFlag == true) {
            binding.ivLowest.visibleOrGone(true) {}
        } else if (!model.disCountInfo?.discountText.isNullOrEmpty()) {
            binding.ivDiscount.visibleOrGone(true){
                text= "Save ${model.disCountInfo?.discountPercent}"
            }
        }

        binding.tagKPay.visibleOrGone(model.klarnaPayFlag == true)
        binding.viewLineFreeShop.visibleOrGone(false)
        binding.tagFreePay.visibleOrGone(model.logistics?.shippingTag?.isNotEmpty() == true) {
            text = model.logistics?.shippingTag
                ?: string(com.starblink.library.widget.R.string.goods_card_free_shopping)
            binding.viewLineFreeShop.visibleOrGone(model.klarnaPayFlag == true)
        }

        binding.logo.setOnClickListener {
            navigationTo(
                RoutePage.Store.PAGE_HOME,
            ) {
                extraOf(
                    RoutePage.Store.ID to merchant?.id
                )
            }
        }
        binding.logo.trackData(
            page = spmPageValue,
            element = SpmElementDef.StoreIcon_33032,
            params = spmMap(model, position),
            businessSuffixID = model.id + "_$pageTrackTag",
//            businessSuffixID = businessSuffixId(model),
        )

        binding.tvMerchantName.setOnClickListener {
            navigationTo(
                RoutePage.Store.PAGE_HOME,
            ) {
                extraOf(
                    RoutePage.Store.ID to merchant?.id
                )
            }
        }

        binding.vClickBuy.trackData(
            page = if (spmPageValue == 10028) 10210 else spmPageValue,
            element = SpmElementDef.ProductDetailNewBodyBuy,
            onlyHit = true,
            params = SpmTrackHandler.trackProductOfferMap(position, product = model),
        )
        binding.vClickBuy.setOnClickListener {
            /*navigationTo(RoutePage.Product.PAGE_LINK) {
                extraOf(
                    RoutePage.ARG.ID to model.id,
                    RoutePage.Product.TYPE to model.type,
                    RoutePage.Product.COLLECT to model.collected,
                    RoutePage.Store.URL to (model.affInfo?.link ?: model.url),
                    RoutePage.Store.STORE_ID to merchant?.id,
                    RoutePage.Store.SUB_OR_NOT to merchant?.subOrNot,
                    RoutePage.Store.STORE_NAME to merchant?.merchantName,
                    RoutePage.Store.STORE_LOGO to merchant?.logo,
                )
            }*/
            CommonRoute.startProductLink(
                itemView.context,
                webUrl = model.url,
                id = model.id ?: "",
                productId = model.productId ?: "",
                standardSpuIds = model.standardSpuIds ?: "",
                collect = model.collected ?: false,
                type = model.type,
                storeId = merchant?.id ?: "",
                storeName = merchant?.merchantName ?: "",
                storeLogo = merchant?.logo,
                storeFollow = merchant?.subOrNot ?: false,
                affInfoLink = model.affInfo?.link,
            )
        }

        bindSubState(model, position)
    }

    private fun bindSubState(model: ProductOffer, position: Int) {
        val merchant = model.merchantWeb?.merchantWebVOF
        binding.imgMerchantSub.setImageResource(if (merchant?.subOrNot == true) R.mipmap.icon_web_followed else R.mipmap.icon_web_follow)
        binding.imgMerchantSub.setOnClickListener {
            merchant ?: return@setOnClickListener
            CommonMutateManage.subscribeOrNotMerchant(
                itemView.context,
                merchantId = merchant.id,
                merchantName = merchant.merchantName,
                subOrNot = merchant.subOrNot,
                resultCallback = null,
            )

            SpmTrackHandler.addSingleTrackData(
                SkAntEntity(
                    spmCnt = GTrackerAssistUtils.fetchElementValue(
                        spmPageValue,
                        SpmElementDef.StoreSub
                    ),
                    params = spmMap(model, position).apply {
                        put("status", if (UserDataCenter.isLogin()) "1" else "0")
                        put(
                            "result",
                            if (model.merchantWeb?.merchantWebVOF?.subOrNot == true) "0" else "1"
                        )
                    }
                )
            )
        }
    }

}